import { dialog } from 'electron';
import Fs from 'fs';
import Path from 'path';

export class MainUtlis {

    /**
     * 选择本地文件
     */
    static async selectLocalFiles() {
        // 弹窗选择文件
        const result = await dialog.showOpenDialog({
            filters: [{
                name: 'Spine 资源文件',
                // extensions: ['json', 'skel', 'png', 'atlas'],
                extensions: ['json','skel'],
            }],
            properties: ['openFile', 'multiSelections'],
            message: '请选择骨骼动画资源',
        });
        // 取消
        if (!result || result.canceled) {
            return;
        }
        const paths = result.filePaths || result;
        return paths;
    }

    /**
     * 通过路径识别资源
     * @param {string[]} paths 
     */
    static identifyByPaths(paths) {

        // 资源路径
        let spinePath, texturePath, atlasPath;
        // 遍历选中的文件路径
        for (let i = 0; i < paths.length; i++) {
            const path = paths[i],
                extname = Path.extname(path);
            switch (extname) {
                case '.json':
                case '.skel': {
                    spinePath = path;
                    break;
                }
                case '.png': {
                    texturePath = path;
                    break;
                }
                case '.atlas':
                case '.txt': {
                    atlasPath = path;
                    break;
                }
            }
            // 只识别一套资源
            if (spinePath && texturePath && atlasPath) {
                break;
            }
        }
        // 是否有选中 spine 资源
        if (!spinePath) {
            console.warn('未选中 spine 资源');
            return;
        }
        // 处理路径
        paths = { spinePath, texturePath, atlasPath };
        const assets = this.collectAssets(paths);
        if (!assets) { return; }
        return this.processAssetPaths(assets);
    }

    /**
     * 收集资源
     * @param {{ spinePath: string, texturePath: string, atlasPath: string }} paths 资源路径
     */
    static collectAssets(paths) {
        let { spinePath, texturePath, atlasPath } = paths;
        // 纹理资源
        if (!texturePath) {
            // 暴力查找
            texturePath = this.getRelatedFile(spinePath, 'png');
        }
        // 找不到纹理啊
        if (!texturePath) {
            console.warn('未找到纹理资源');
            return null;
        }
        // 图集资源
        if (!atlasPath) {
            // 暴力查找
            atlasPath = this.getRelatedFile(spinePath, 'atlas');
            // 还没有的话再试试 txt 格式
            if (!atlasPath) {
                atlasPath = this.getRelatedFile(spinePath, 'txt');
            }
            // 还没有的话再试试 atlas.txt 格式
            if (!atlasPath) {
                atlasPath = this.getRelatedFile(spinePath, 'atlas.txt');
            }
        }
        // 找不到图集啊
        if (!atlasPath) {
            console.warn('未找到图集资源');
            return null;
        }
        // 文件类型（json 或 skel）
        const spineType = Path.extname(spinePath);
        // 打包资源信息
        const assets = {
            // 目录路径
            dir: undefined,
            // 骨骼数据（JSON）
            json: (spineType === '.json') ? spinePath : undefined,
            // 骨骼数据（二进制）
            skel: (spineType === '.skel') ? spinePath : undefined,
            // 纹理
            png: texturePath,
            // 图集
            atlas: atlasPath,
        };
        return assets;
    }

    /**
     * 查找相关联的文件路径
     * @param {string} filePath 文件路径
     * @param {string} relatedExt 关联文件的扩展名
     * @returns {string}
     */
    static getRelatedFile(filePath, relatedExt) {
        const dirPath = Path.join(Path.dirname(filePath), Path.sep),
            basename = Path.basename(filePath, Path.extname(filePath)).replace(/(-pro|-ess|-pma)/, ''),
            basePath = Path.join(dirPath, basename),
            testList = [
                `${basePath}.${relatedExt}`,
                `${basePath}-pma.${relatedExt}`,
                `${basePath}-pro.${relatedExt}`,
                `${basePath}-ess.${relatedExt}`
            ];
        for (let i = 0; i < testList.length; i++) {
            if (Fs.existsSync(testList[i])) {
                return testList[i];
            }
        }
        return null;
    }

    /**
    * 处理资源路径
    */
    static processAssetPaths(assets) {
        const { dir, json, skel, png, atlas } = assets;
        if (!dir) {
            assets.dir = Path.dirname(json || skel);
        }
        if (!assets.dir.endsWith(Path.sep)) {
            assets.dir += Path.sep;
        }
        if (json) {
            assets.json = Path.basename(json);
        } else if (skel) {
            assets.skel = Path.basename(skel);
        }
        assets.atlas = Path.basename(atlas);
        assets.png = Path.basename(png);
        return assets;
    }

    /**
     * 获取资源对应的 Spine 运行时版本
     * @param {Object} assets 资源信息
     * @returns {string}
     */
    static getAssetSpineVersion(assets) {
        let path = assets.json || assets.skel;
        const fullPath = Path.join((assets.dir || ''), path);
        let version='3.8';

        if (!Fs.existsSync(fullPath)) {
            return version;
        }
        const extname = Path.extname(path);
        if (extname === '.json') {
            const data = JSON.parse(Fs.readFileSync(fullPath, 'utf-8'));
            if (data.skeleton) {
                version=data.skeleton.spine;
            }
        } else if (extname === '.skel') {
            return '3.8';
        }
        version = version.split('.').slice(0, 2).map(v => parseInt(v)).join('.');

        return version;
    }

}